<script lang="ts" setup>
  import { ref, computed, watch } from 'vue';
  import {
    Card,
    Button,
    Modal,
    Checkbox,
    Tag,
    InputSearch,
    Spin,
    Message,
    Radio,
    Dropdown,
    Doption,
    Popover,
    InputNumber,
    Pagination,
  } from '@arco-design/web-vue';
  import { IconArrowLeft, IconDown } from '@arco-design/web-vue/es/icon';
  import VueDraggable from 'vuedraggable';
  import {
    querySpColumnInfo,
    addArticleToSpColumn,
    querySpColumnList,
    changeArticleIndexOnSpColumn,
    deleteArticleFromSpColumn,
    addArticleToOtherSpColumn,
  } from '/@/api/column';
  import type { SpColumnRecord } from '/@/api/model/columnModel';
  import { queryArticleList, queryArticlePage } from '/@/api/article';
  import type { ArticleRecord } from '/@/api/model/articleModel';
  import { useRoute } from 'vue-router';

  const route = useRoute();
  const getSpColumnId = computed(() => {
    return parseInt(route.params.sp_column_id as string, 10) || 0;
  });
  const AddArticleToOtherSpColumnModalVisible = ref(false);
  const addArticleToOtherSpColumnLoadingRef = ref(false);
  interface AddArticleToSpColumnRecord {
    raw: SpColumnRecord;
  }
  const spColumnListRef = ref<AddArticleToSpColumnRecord[]>([]);
  const addArticleToOtherSpColumnTitleSearchRef = ref('');
  const addArticleLoadingRef = ref(false);
  const spColumnSelectedId = ref<number>();
  interface AddArticleRecord {
    raw: ArticleRecord;
    selected: boolean;
  }
  // 待添加文章列表
  const addArticleList = ref<AddArticleRecord[]>([]);
  // 已选待添加文章 id 列表
  const getAddArticleSelectedIdList = computed(() => {
    return addArticleList.value.filter((item) => item.selected).map((item) => item.raw.id);
  });
  // 是否全选
  const getAddArticleAllSelected = computed(() => {
    return addArticleList.value.length > 0 && addArticleList.value.every((item) => item.selected);
  });
  // 是否选择一部分
  const getAddArticleAllIndeterminate = computed(() => {
    return (
      addArticleList.value.length > 0 &&
      !getAddArticleAllSelected.value &&
      addArticleList.value.some((item) => item.selected)
    );
  });
  const spColumnInfoRef = ref<SpColumnRecord>();
  interface SpColumnArticleRecord {
    raw: ArticleRecord;
    selected: boolean;
    popover: boolean;
    index: number;
    tempIndex: number;
    id: number;
  }
  // 管理文章列表
  const spColumnArticleListRef = ref<SpColumnArticleRecord[]>([]);
  const spColumnArticleListLoading = ref(false);
  // 已选管理文章 id 列表
  const getSpColumnArticleSelectedIdList = computed(() => {
    return spColumnArticleListRef.value.filter((item) => item.selected).map((item) => item.raw.id);
  });
  // 是否全选
  const getSpColumnArticleAllSelected = computed(() => {
    return (
      spColumnArticleListRef.value.length > 0 &&
      spColumnArticleListRef.value.every((item) => item.selected)
    );
  });
  // 是否选择一部分
  const getSpColumnArticleAllIndeterminate = computed(() => {
    return (
      spColumnArticleListRef.value.length > 0 &&
      !getSpColumnArticleAllSelected.value &&
      spColumnArticleListRef.value.some((item) => item.selected)
    );
  });
  // const articleListRef = ref();
  const modelVisible = ref(false);
  const articleTitleSearchRef = ref('');
  type SortTypeKey = 0 | 1 | 2;
  interface SortTypeRecord {
    label: string;
    key: SortTypeKey;
  }
  const sortTypeListRef = ref<SortTypeRecord[]>([
    { label: '默认排序', key: 0 },
    { label: '最早发布', key: 1 },
    { label: '最新发布', key: 2 },
  ]);
  const selectedSortTypeKeyRef = ref<SortTypeKey>(0);
  const getSortType = computed(() => {
    return sortTypeListRef.value.find((item) => item.key === selectedSortTypeKeyRef.value);
  });

  const onPopupVisibleChange = (visible: boolean, item: SpColumnArticleRecord) => {
    item.popover = visible;
    item.tempIndex = item.index;
  };

  // 拖拽排序
  const onArticleDragChange = async ({
    moved,
  }: {
    moved: { newIndex: number; element: SpColumnArticleRecord };
  }) => {
    if (moved) {
      const { element: item, newIndex } = moved;
      await changeArticleIndexOnSpColumn(item.raw.id, newIndex + 1, getSpColumnId.value);
      reloadSpColumnArticleList();
    }
  };

  // 排序索引变化
  const onIndexChange = async (item: SpColumnArticleRecord) => {
    await changeArticleIndexOnSpColumn(item.raw.id, item.tempIndex, getSpColumnId.value);
    reloadSpColumnArticleList();
  };

  // 排序类型变化
  const onSortTypeChange = (item: SortTypeRecord) => {
    selectedSortTypeKeyRef.value = item.key;
    reloadSpColumnArticleList();
  };

  // 将文章添加至专栏
  const onAddArticle = async () => {
    try {
      await addArticleToSpColumn(getAddArticleSelectedIdList.value, getSpColumnId.value);
      reloadSpColumnArticleList();
      Message.success('操作成功！');
    } catch (error) {
      Message.error((error as Error).message || '操作失败');
      return false;
    }
  };

  // 全选管理文章列表
  const onSelectAll = () => {
    if (!getSpColumnArticleAllSelected.value) {
      spColumnArticleListRef.value.forEach((item) => (item.selected = true));
    } else {
      spColumnArticleListRef.value.forEach((item) => (item.selected = false));
    }
  };

  // 全选待添加文章列表
  const onSelectAllAddArticleList = () => {
    if (!getAddArticleAllSelected.value) {
      addArticleList.value.forEach((item) => (item.selected = true));
    } else {
      addArticleList.value.forEach((item) => (item.selected = false));
    }
  };

  // 刷新待添加文章列表
  const reloadArticleListForSpColumn = async () => {
    addArticleLoadingRef.value = true;
    try {
      const result = await queryArticleList({
        title: articleTitleSearchRef.value,
      });
      addArticleList.value = result.map((item) => {
        return {
          raw: item,
          selected: false,
        };
      });
    } finally {
      addArticleLoadingRef.value = false;
    }
  };

  // 刷新待添加专栏列表
  const reloadSpColumnList = async () => {
    addArticleToOtherSpColumnLoadingRef.value = true;
    try {
      const result = await querySpColumnList({
        name: addArticleToOtherSpColumnTitleSearchRef.value,
      });
      spColumnListRef.value = result.map((item) => {
        return {
          raw: item,
        };
      });
    } finally {
      addArticleToOtherSpColumnLoadingRef.value = false;
    }
  };

  // 打开添加文章弹窗
  const openOperateArticleCurrentSpColumnModal = async () => {
    modelVisible.value = true;
    reloadArticleListForSpColumn();
  };

  // 打开添加文章到其他专栏弹窗
  const openAddArticleToSpColumnModal = async () => {
    AddArticleToOtherSpColumnModalVisible.value = true;
    spColumnSelectedId.value = undefined;
    reloadSpColumnList();
  };

  // 刷新专栏文章列表
  const spColumnArticleListPageRef = ref(1);
  const spColumnArticleListTotalRef = ref(0);
  const reloadSpColumnArticleList = async () => {
    spColumnArticleListLoading.value = true;
    try {
      const result = await queryArticlePage({
        sp_column_id: getSpColumnId.value,
        // sort: selectedSortTypeKeyRef.value,
        title: '',
        page: spColumnArticleListPageRef.value,
        size: 20,
      });
      const list = result.list.map((item, index) => {
        return {
          raw: item,
          selected: false,
          popover: false,
          index: index + 1,
          tempIndex: index + 1,
          id: item.id,
        } as SpColumnArticleRecord;
      });
      spColumnArticleListRef.value = list;
      spColumnArticleListTotalRef.value = result.pagination.total;
    } finally {
      spColumnArticleListLoading.value = false;
    }
  };

  // 取消收录
  const removeArticleFromCurrentSpColumn = () => {
    Modal.info({
      title: '取消收录',
      content: '确认将该文章从此专栏里取消收录？取消收录后将无法在此专栏里访问相关文章。',
      onOk: async () => {
        try {
          const ids = spColumnArticleListRef.value
            .filter((item) => {
              return item.selected;
            })
            .map((item) => item.raw.id);
          await deleteArticleFromSpColumn(ids, getSpColumnId.value);
          reloadSpColumnArticleList();
          Message.success('操作成功！');
        } catch (error) {
          Message.error((error as Error).message || '操作失败');
          return false;
        }
      },
    });
  };

  // 移动文章到其他专栏
  const onAddArticleToOtherSpColumn = async () => {
    try {
      if (typeof spColumnSelectedId.value !== 'undefined') {
        const ids = spColumnArticleListRef.value
          .filter((item) => {
            return item.selected;
          })
          .map((item) => item.raw.id);
        await addArticleToOtherSpColumn(ids, spColumnSelectedId.value, getSpColumnId.value);
        reloadSpColumnArticleList();
        Message.success('操作成功！');
      }
    } catch (error) {
      Message.error((error as Error).message || '操作失败');
      return false;
    }
  };

  // 选择待添加的文章
  const onSelectArticle = (item: AddArticleRecord) => {
    item.selected = !item.selected;
  };

  // 选择待转移的专栏
  const onSelectSpColumn = (item: AddArticleToSpColumnRecord) => {
    spColumnSelectedId.value = item.raw.id;
  };

  // 更新专栏信息
  const reloadSpColumnInfo = async () => {
    spColumnInfoRef.value = await querySpColumnInfo(getSpColumnId.value);
  };

  // 触发更新
  watch(
    getSpColumnId,
    async () => {
      reloadSpColumnInfo();
      reloadSpColumnArticleList();
    },
    { immediate: true },
  );
</script>

<template>
  <Card class="min-h-[calc(100vh-140px)]" :bodyStyle="{ padding: 0 }">
    <template #title>
      <div class="flex">
        <RouterLink to="/creator/content/sp_column"><IconArrowLeft /></RouterLink>
        <div class="ml-[16px]">{{ spColumnInfoRef?.name }}</div>
      </div>
    </template>
    <Button
      class="absolute right-[30px] top-[7px]"
      type="primary"
      @click="openOperateArticleCurrentSpColumnModal"
      >添加文章</Button
    >
    <Spin :loading="spColumnArticleListLoading" class="w-full h-full min-h-[300px] pb-[20px]">
      <div class="px-[20px] sticky top-0 left-0 bg-white z-10">
        <div
          class="h-[56px] flex items-center justify-between border-b-[1px] border-gray-300 pl-[18px] pr-[12px] text-black"
        >
          <div class="space-x-[12px]">
            <Checkbox
              :modelValue="getSpColumnArticleAllSelected"
              :indeterminate="getSpColumnArticleAllIndeterminate"
              @change="onSelectAll"
              >全选</Checkbox
            >
            <Button
              @click="openAddArticleToSpColumnModal"
              type="outline"
              :disabled="getSpColumnArticleSelectedIdList.length < 1"
              >移动至专栏</Button
            >
            <Button
              @click="removeArticleFromCurrentSpColumn"
              type="outline"
              status="danger"
              :disabled="getSpColumnArticleSelectedIdList.length < 1"
              >取消收录</Button
            >
          </div>
          <div class="flex items-center">
            <Dropdown>
              <Button type="text" class="text-black">{{ getSortType?.label }} <IconDown /></Button>
              <template #content>
                <Doption
                  v-for="item in sortTypeListRef"
                  :key="item.key"
                  @click="onSortTypeChange(item)"
                  :class="{ 'text-[#5f70ff]': item.key === selectedSortTypeKeyRef }"
                  >{{ item.label }}</Doption
                >
              </template>
            </Dropdown>
            <div class="w-[80px] text-right" v-if="selectedSortTypeKeyRef === 0">设置顺序</div>
          </div>
        </div>
      </div>
      <VueDraggable
        :modelValue="spColumnArticleListRef"
        @change="onArticleDragChange"
        item-key="id"
      >
        <template #item="{ element: item }">
          <div
            class="cursor-pointer hover:bg-gray-100 px-[20px] group"
            :class="{ 'bg-gray-100': item.selected }"
            draggable="true"
          >
            <a
              class="h-[56px] flex items-center justify-between border-b-[1px] border-gray-300 group-last:border-b-0 pl-[18px] pr-[12px]"
              :href="`/post/${item.raw.id}`"
              target="_blank"
            >
              <div class="flex group">
                <div class="w-[24px] flex items-center justify-center text-center">
                  <Checkbox
                    class="p-0 hidden group-hover:flex"
                    :class="{ '!flex': item.selected }"
                    v-model="item.selected"
                    @click.stop
                  />
                  <span class="group-hover:hidden" :class="{ '!hidden': item.selected }">{{
                    item.index
                  }}</span>
                </div>
                <div class="ml-[8px] text-black">{{ item.raw.title }}</div>
              </div>
              <div class="text-[14px] text-gray-400 flex">
                <div>{{ item.raw.updateTime }}</div>
                <Popover
                  :trigger="['click']"
                  :popupVisible="item.popover"
                  @popupVisibleChange="($event) => onPopupVisibleChange($event, item)"
                  position="br"
                  v-if="selectedSortTypeKeyRef === 0"
                >
                  <div class="hover:text-[#5f70ff] w-[80px] text-right" @click.stop.prevent
                    >修改</div
                  >
                  <template #content>
                    <div class="space-y-[8px]">
                      <div class="flex items-center">
                        <div>设置文章顺序为</div>
                        <div class="ml-[10px] space-x-[6px]"
                          ><span>第</span
                          ><InputNumber
                            class="w-[60px]"
                            :min="1"
                            :max="spColumnArticleListRef.length"
                            v-model:modelValue="item.tempIndex"
                          /><span>位</span></div
                        >
                      </div>
                      <div class="flex justify-end space-x-[8px]">
                        <Button size="mini" @click="item.popover = false">取消</Button>
                        <Button size="mini" type="primary" @click="onIndexChange(item)"
                          >确定</Button
                        >
                      </div>
                    </div>
                  </template>
                </Popover>
              </div>
            </a>
          </div>
        </template>
      </VueDraggable>
      <Pagination
        class="mt-[20px] justify-end"
        :total="spColumnArticleListTotalRef"
        :current="spColumnArticleListPageRef"
      />
    </Spin>
    <Modal
      :width="760"
      v-model:visible="modelVisible"
      :closable="false"
      bodyClass="p-0 h-[392px]"
      okText="移动"
      :onBeforeOk="onAddArticle"
    >
      <template #title>
        <div class="w-full flex items-center justify-between">
          <div class="flex">
            <div class="text-[16px] text-black font-bold">将文章添加至此专栏</div>
            <div class="mx-[14px] text-gray-300">|</div>
            <div class="text-gray-300 text-[14px]">已同时收录于三专栏的文章将不在列表</div>
          </div>
          <div
            ><InputSearch
              v-model="articleTitleSearchRef"
              placeholder="请输入标题关键词"
              @keypress.enter="reloadArticleListForSpColumn"
              @search="reloadArticleListForSpColumn"
          /></div>
        </div>
      </template>
      <Spin :loading="addArticleLoadingRef" class="w-full h-full">
        <div class="px-[20px] sticky top-0 left-0 bg-white z-10">
          <div
            class="h-[56px] flex items-center border-b-[1px] border-gray-300 space-x-[12px] pr-[12px]"
          >
            <Checkbox
              :modelValue="getAddArticleAllSelected"
              :indeterminate="getAddArticleAllIndeterminate"
              @change="onSelectAllAddArticleList"
              >全选</Checkbox
            >
            <Tag bordered>已选 {{ getAddArticleSelectedIdList.length }} 项</Tag>
          </div>
        </div>
        <div>
          <div
            v-for="item in addArticleList"
            :key="item.raw.id"
            class="cursor-pointer hover:bg-gray-100 px-[20px] group"
          >
            <div
              class="h-[56px] flex items-center justify-between border-b-[1px] border-gray-300 group-last:border-b-0 pr-[12px]"
              @click="onSelectArticle(item)"
            >
              <div class="flex">
                <Checkbox :modelValue="item.selected" />
                <div class="ml-[8px] text-black">{{ item.raw.title }}</div>
              </div>
              <div class="text-[14px] text-gray-400">{{ item.raw.updateTime }}</div>
            </div>
          </div>
        </div>
      </Spin>
    </Modal>
    <Modal
      :width="760"
      v-model:visible="AddArticleToOtherSpColumnModalVisible"
      :closable="false"
      bodyClass="p-0 h-[392px]"
      okText="移动"
      :onBeforeOk="onAddArticleToOtherSpColumn"
    >
      <template #title>
        <div class="w-full flex items-center justify-between">
          <div class="flex">
            <div class="text-[16px] text-black font-bold">将文章移动至其他专栏</div>
            <div class="mx-[14px] text-gray-300">|</div>
            <div class="text-gray-300 text-[14px]">每次仅能选择一个专栏</div>
          </div>
          <div
            ><InputSearch
              v-model="addArticleToOtherSpColumnTitleSearchRef"
              @search="reloadSpColumnList"
              @keypress.enter="reloadSpColumnList"
              placeholder="请输入标题关键词"
          /></div>
        </div>
      </template>
      <Spin :loading="addArticleToOtherSpColumnLoadingRef" class="w-full h-full">
        <div>
          <div
            v-for="item in spColumnListRef"
            :key="item.raw.id"
            class="cursor-pointer hover:bg-gray-100 px-[20px] group"
          >
            <div
              class="h-[56px] flex items-center justify-between border-b-[1px] border-gray-300 group-last:border-b-0 pr-[12px]"
              @click="onSelectSpColumn(item)"
            >
              <div class="flex">
                <Radio :modelValue="spColumnSelectedId === item.raw.id" />
                <div class="ml-[8px] text-black">{{ item.raw.name }}</div>
              </div>
              <div class="text-[14px] text-gray-400">{{ item.raw.updateTime }}</div>
            </div>
          </div>
        </div>
      </Spin>
    </Modal>
  </Card>
</template>
